home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MOS / XBRA.D < prev    next >
Encoding:
Modula Definition  |  1990-10-24  |  8.9 KB  |  218 lines

  1.  
  2. DEFINITION MODULE XBRA;
  3.  
  4. (*
  5.  * Universelle XBRA-Funktionen                        Version 1.2  vom 24.10.90
  6.  *
  7.  * Erstellt von Thomas Tempelmann.
  8.  *
  9.  * Die vorhandenen Funktionen bieten alles, um auf einfache Weise installierte
  10.  * Vektoren zu erkunden (wahlweise alle oder einen spezifischen) und sie
  11.  * korrekt ein-, bzw. wieder auszutragen.
  12.  *
  13.  * Wurde eine Funktion installiert, kann durch die Funktion 'PreviousEntry' die
  14.  * vorher installierte Routine ermittelt werden. Damit ist es dann möglich,
  15.  * den Vorgänger in der Funktion selbst aufzurufen, falls dies nötig wäre.
  16.  * Die zum Aufrufen notwendigen Funktionen sind jedoch nicht Bestandteil
  17.  * dieser XBRA-Library, da sie erstens Compiler-spezifisch und zweitens
  18.  * sie je nach Anwendung sehr unterschiedlich implementiert werden müssen.
  19.  *
  20.  * Die Funktionen sind so ausgelegt, daß sie normalerweise im User-Mode
  21.  * aufgerufen werden und selbst beim Zugriff über die Vektoren in den Super-
  22.  * visor-Mode wechseln (das Programm darf sich aber auch bereits im Supervi-
  23.  * sor-Mode befinden). Dies erleichtert dem Programmierer die Anwendung der
  24.  * Funktionen. Da die Anwendungen beim Installieren von Vektoren in der Regel
  25.  * nicht zeitkritisch ausgelegt sein brauchen, sollte man diese Komfortabilität
  26.  * dem leichten Zeitverlust durch - meist - zwei statt nur einem Wechsel vom
  27.  * User- in den Supervisor-Mode vorziehen.
  28.  *
  29.  *
  30.  * Hier noch eine allgemeine Beschreibung zur Anwendung der Funktionen:
  31.  *
  32.  * Folgendermaßen sieht eine XBRA-Installation aus:
  33.  *
  34.  *   vector:= 400H; (* z.B. der 'etv_timer'-Vektor *)
  35.  *   IF NOT Installed ('Test', vector, at) THEN
  36.  *     Create (carrier, 'Test', ADDRESS (TestProzedur), entry);
  37.  *     Install (entry, at)
  38.  *   END;
  39.  *
  40.  * 'Installed' prüft, ob die Funktion schon mit XBRA-Kennung installiert
  41.  * ist. Wenn nicht, wird mit 'Create' ein XBRA-Header erzeugt, der neben
  42.  * der XBRA-Informationen auch eine Sprunganweisung enthält. Der so
  43.  * erzeugte Header wird dann mit 'Install' als erster neuer Vektor
  44.  * eingetragen und die XBRA-Verkettung erzeugt.
  45.  *
  46.  * Da je nach Implementation verschiedene Prozeduren mit beliebigen
  47.  * Parametern verwendet werden könnten, und der XBRA-Header nur einfach
  48.  * dazwischengesetzt wird, ist die Prozeduradresse 'call' als ADDRESS
  49.  * deklariert. Für die korrekte Parameterübergabe haben nicht die XBRA-
  50.  * Funktionen zu sorgen, sondern schon die Routine, die zu installierende
  51.  * Funktion über den Vektor aufruft.
  52.  *
  53.  * Zum Vergleich obige Installation ohne XBRA:
  54.  *   vector:= 400H;  (* VAR vector: POINTER TO ADDRESS *)
  55.  *   vector^:= ADDRESS (TestProzedur);
  56.  * Falls es Probleme gibt, sollte erst das Programm ohne XBRA zum Laufen
  57.  * gebracht werden, und dann erst die XBRA-Installation eingefügt werden.
  58.  * Z.B. ist zu beachten, daß normalerweise Installationen über externe
  59.  * Vektoren über die Funktionen aus dem Modul 'Calls' vorgenommen werden
  60.  * sollten. Dies bleibt auch so, wenn dann die XBRA-Funktionen zuhilfe
  61.  * genommen werden!
  62.  *
  63.  * Soll die Funktion später wieder aus der Vektor-Kette ausgehängt werden,
  64.  * geht das so:
  65.  *
  66.  *   IF Installed ('Test', vector, at) THEN
  67.  *     Remove (at)
  68.  *   END
  69.  *
  70.  * Bei 'PreviousEntry' (s.o.) wird der bei 'Create' erhaltene 'entry'-Wert
  71.  * wieder übergeben, um z.B. in 'TestProzedur' den Vorgänger zu
  72.  * ermitteln und dann ggf. aufzurufen.
  73.  *
  74.  * 'Query' dient dazu, alle installierten XBRA-Kennungen einer Vektor-
  75.  * Kette zu ermitteln. Dabei können auch z.B. mit folgender Routine alle
  76.  * installierten XBRA-Vektoren ausgehängt werden:
  77.  *
  78.  *   PROCEDURE RemoveAll (vector: ADDRESS);
  79.  *
  80.  *     PROCEDURE step (at: ADDRESS; name: Str4): BOOLEAN;
  81.  *       (* darf lokal sein *)
  82.  *       BEGIN
  83.  *         (*
  84.  *          * Hier könnten der jeweilige Vorgänger mit
  85.  *          *  'PreviousEntry ( Entry (at) )'
  86.  *          * oder die Adr. der aufgerufenen Prozedur mit
  87.  *          *  'Called (at)'  ermittelt und angezeigt werden.
  88.  *          *)
  89.  *         IF prev # NIL THEN (* ist dies ein XBRA-Eintrag? *)
  90.  *           Remove (at)      (* -> nur dann kann er entfernt werden *)
  91.  *         END;
  92.  *         RETURN TRUE        (* weitermachen, solange die Kette weitergeht *)
  93.  *       END step;
  94.  *
  95.  *     BEGIN
  96.  *       Query (vector, step)
  97.  *     END RemoveAll;
  98.  *
  99.  *
  100.  * Die Demo-Programme 'KbdTest' und 'ExcDemo' im UTILITY-Ordner zeigen
  101.  * die Anwendung dieses Moduls.
  102.  *)
  103.  
  104. (*$H+*)
  105.  
  106. FROM SYSTEM IMPORT ADDRESS;
  107.  
  108. TYPE
  109.  
  110.   ID = ARRAY [0..3] OF CHAR;            (* String zur Aufnahme der Kennung *)
  111.  
  112.   JmpCarrier = RECORD                   (* Interne Datenstruktur!     *)
  113.                  jmpInstr: CARDINAL;    (*  - nicht darauf zugreifen! *)
  114.                  operand: ADDRESS
  115.                END;
  116.  
  117.   Carrier = RECORD      (* Interne Datenstruktur - nicht darauf zugreifen! *)
  118.               magic: ID;                (* CONST 'XBRA' *)
  119.               name : ID;                (* individuelle Kennung *)
  120.               prev : ADDRESS;           (* voriger Vektor *)
  121.               entry: JmpCarrier;
  122.             END;
  123.  
  124.   QueryProc = PROCEDURE ( (* at  : *) ADDRESS,
  125.                           (* name: *) ID      ): (* continue: *) BOOLEAN;
  126.  
  127.  
  128. (*
  129.  * Funktionen für die XBRA-Installation
  130.  * ------------------------------------
  131.  *)
  132.  
  133. PROCEDURE Create (VAR use: Carrier; name: ID; call: ADDRESS;
  134.                   VAR entry: ADDRESS);
  135.   (*
  136.    * Erzeugt einen XBRA-Header mit einer Sprunganweisung zur Prozedur 'call'.
  137.    * Achtung: die Carrier-Variable muß global (statisch) deklariert sein -
  138.    *   sie muß so lange erhalten bleiben, wie die XBRA-Einbindung besteht!
  139.    * Der erhaltene 'entry'-Wert kann daraufhin mittels der Prozedur 'Install'
  140.    * in den gewünschten Vektor eingetragen werden.
  141.    *)
  142.  
  143. PROCEDURE Installed (name: ID; vector: ADDRESS; VAR at: ADDRESS): BOOLEAN;
  144.   (*
  145.    * Wird 'name' in Kette ab 'vector' gefunden, enthält 'at' die Adresse
  146.    * des Vektors auf den Funktionseinsprung (welcher Teil von 'Carrier' ist).
  147.    * Wird 'name' nicht gefunden, ist 'at'=vector
  148.    *)
  149.  
  150. PROCEDURE Install (entry: ADDRESS; at: ADDRESS);
  151.   (*
  152.    * Fügt einen XBRA-Header 'entry' im Vektor 'at' ein. Der alte Vektorinhalt
  153.    * wird im XBRA-Header gesichert und kann mittels 'PreviousEntry' abgefragt
  154.    * werden.
  155.    *)
  156.  
  157. PROCEDURE Remove (at: ADDRESS);
  158.   (*
  159.    * Fügt den XBRA-Header, auf den der Vektor bei 'at' zeigt, aus.
  160.    * In den Vektor wird wieder der Vorgänger eingetragen.
  161.    *)
  162.  
  163. (*
  164.  * Funktionen zum Abfragen XBRA-Informationen
  165.  * ------------------------------------------
  166.  *)
  167.  
  168. PROCEDURE Query (vector: ADDRESS; with: QueryProc);
  169.   (*
  170.    * Ruft 'with' für alle im Vektor 'vector' installierten Funktionen auf,
  171.    * solange sie durch XBRA-Strukturen verbunden sind.
  172.    * Die 'with'-Funktion kann 'FALSE' zurückgeben, um die Aufrufe vorzeitig
  173.    * zu beenden.
  174.    * 'with' darf auch eine lokale Prozedur sein.
  175.    *)
  176.  
  177. PROCEDURE Entry (at: ADDRESS): ADDRESS;
  178.   (*
  179.    * Liefert die Adresse, auf die der Vektor 'at' zeigt.
  180.    * Dies ist der "Entry", vor dem ggf. die XBRA-Struktur steht.
  181.    * Das Ergebnis dieser Funktion kann z.B. für die 'PreviousEntry'-Funktion
  182.    * verwendet werden, sollte jedoch nicht zur rein informativen Ermitttelung
  183.    * der in 'at' installierten Funktion verwendet werden - dafür ist 'Called'
  184.    * (s.u.) vorgesehen!
  185.    *)
  186.  
  187. PROCEDURE PreviousEntry (entry: ADDRESS): ADDRESS;
  188.   (*
  189.    * Liefert den "Entry", der vor dem angegebenen "Entry" installiert ist.
  190.    * Diese Funktion kann z.B. in der eigenen installierten Funktion dazu
  191.    * benutzt werden, den Vorgänger aufzurufen (hier sollte aus Effizienz-
  192.    * gründen nicht 'Called' verwendet werden), um eine Aufrufkette zu reali-
  193.    * sieren (ist z.B. beim 200Hz-Vektor sinnvoll, da hier mehrere Routinen
  194.    * hintereinander installiert werden, die alle sich nacheinander aufrufen).
  195.    * Zu diesem Zweck muß dann der bei 'Create' erhaltene 'entry'-Wert über-
  196.    * geben werden. Achtung: Da damit gerechnet werden muß, daß während der
  197.    * Lebzeit des Programms im Speicher die XBRA-Verkettung jederzeit ver-
  198.    * ändert werden kann, darf nicht einmalig fest die Vorgängeradr. abgefragt
  199.    * und dann über eine Programmlokale Variable adressiert werden, sondern
  200.    * muß immer genau dann, wenn sie benötigt wird, mit dieser Funktion ab-
  201.    * gefragt werden. Es sind dabei keine nennenswerten Zeitverluste zu be-
  202.    * fürchten.
  203.    * Wenn 'entry'=NIL, oder kein Vorgänger ermittelt werden kann (keine XBRA-
  204.    * Struktur vorhanden), wird NIL geliefert.
  205.    *)
  206.  
  207. PROCEDURE Called (at: ADDRESS): ADDRESS;
  208.   (*
  209.    * Liefert die korrekte Programmeinsprungstelle, die über den Vektor 'at'
  210.    * erreicht wird. Dies wäre normalerweise identisch mit dem Ergebnis der
  211.    * 'Entry'-Funktion, jedoch wird hier erkannt, wenn diese "Entry"-Stelle
  212.    * nur die von diesem Modul erzeugte Sprunganweisung in die eigentliche
  213.    * Funktion ist, die bei der 'Install'-Funktion angegeben wurde. Dann
  214.    * wird jene Funktionsadresse geliefert.
  215.    *)
  216.  
  217. END XBRA.
  218.